#!@SHELL@
# -*- shell-script -*-

set -eu
[ x"${GMB_SHELL_DEBUG:-no}" = x"no" ] || set -x

. "@pkglibexecdir@/libgmb"
. "@pkglibexecdir@/config"
. "@pkglibexecdir@/command"


# GMB_OPTIONS
#
GMB_OPTIONS='\
## blah
target,t=TARGET[,...]   : select build target(s)          : targets="${targets} $(echo ${2} | gmb_strsplit ',')"
command,c=COMMAND[,...] : select command(s)               : commands="${commands} $(echo ${2} | gmb_strsplit ',')"
run,r                   : run a command in the target env : shift; [ x"${1}" != x"--" ] || shift; GMB_RUN_ARGV="${@}"; set -- "--"; commands="${commands} run"
force,f                 : force selected command          : GMB_FORCE=1
force-all,F             : force all commands              : GMB_FORCE_ALL=1
jobs,j=JOBS             : set build concurrent jobs       : GMB_N_JOBS=${2}
verbose,v               : increase verbose level          : GMB_VERB_LEVEL=$((GMB_VERB_LEVEL + 1))
quiet,q                 : decrease verbose level          : GMB_VERB_LEVEL=$((GMB_VERB_LEVEL - 1))
cmd-verbose,V           : increase commands verbose level : GMB_CMD_VERB_LEVEL=$((GMB_CMD_VERB_LEVEL + 1))
cmd-quiet,Q             : decrease commands verbose level : GMB_CMD_VERB_LEVEL=$((GMB_CMD_VERB_LEVEL - 1))
'


# setup_command_line_parser
#
setup_command_line_parser()
{
    local short_options=
    local long_options=
    
    while read line; do
        line=$(echo "${line%%##*}" | gmb_strstrip) # strip blanks and comments
        [ x"${line}" != x ] || continue
        
        local optlist=$(echo "${line%%:*}" | gmb_strstrip)
        local optparam="${optlist#*=}"
        [ x"${optparam}" != x"${optlist}" ] || optparam=
        optlist="${optlist%%=*}"
        line="${line#*:}"
        
        local optdescr=$(echo "${line%%:*}" | gmb_strstrip)
        line="${line#*:}"
        local optcode=$(echo "${line}" | gmb_strstrip)
        
        local optname=
        while [ x"${optlist}" != x ]; do
            local opt="${optlist%%,*}"
            [ x"${opt}" != x"${optlist}" ] && optlist="${optlist#*,}" || optlist=
            local optflat=$(echo "${opt}" | sed -e 's,[-],_,g')
            if [ x"${optname}" = x ]; then
                optname="${optflat}"
                printf "local optcode_${optname}='${optcode}'\n"
                [ x"${optparam}" = x ] || printf "local optshift_${optname}=2\n"
            fi
            printf "local optname_${optflat}='${optname}'\n"

            if [ ${#opt} -eq 1 ]; then
                short_options="${short_options}${opt}"
                [ x"${optparam}" = x ] || short_options="${short_options}:"
            else
                [ x"${long_options}" = x ] \
                    && long_options="${opt}" \
                        || long_options="${long_options},${opt}"
                [ x"${optparam}" = x ] || long_options="${long_options}:"
            fi
        done
    done

    printf "local short_options='${short_options}'\n"
    printf "local long_options='${long_options}'\n"
}


# parse_command_line
#
parse_command_line()
{
    local setup=$(echo "${GMB_OPTIONS}" | setup_command_line_parser)
    eval "${setup}"

    local last_targets=
    local last_commands=
    local last_objects=
    while [ ${#} -gt 0 ]; do
        local args=$(getopt --name 'gmb' --shell 'sh' --options "+${short_options}" --long "${long_options}" -- "${@}") || r=$?
        eval set -- "${args}"
        #
        local targets=
        local commands=
        while [ ${#} -gt 0 ]; do
            local opt=
            case "${1}" in
                --) shift; break;;
                --*) opt=$(echo "${1}" | cut -b3-);;
                -*) opt=$(echo "${1}" | cut -b2-);;
                *) gmb_error "oups: '${1}'"
            esac
            local optname=$(eval "echo \${optname_${opt}}")
            local optcode=$(eval "echo \${optcode_${optname}}")
            eval "${optcode}" || gmb_error "optcode failed: '${optcode}'"
            shift $(eval "echo \${optshift_${optname}:-1}")
        done
        [ x"${targets}" = x ] && targets="${last_targets}" || last_targets="${targets}"
        [ x"${commands}" = x ] && commands="${last_commands}" || last_commands="${commands}"
        local objects=
        while [ ${#} -gt 0 ]; do
            case "${1}" in
                -*) break;;
                *) objects="${objects} ${1}"; shift;;
            esac
        done
        [ x"${objects}" = x ] && objects="${last_objects}" || last_objects="${objects}"
        gmb_manager_process_order -c "${commands}" -t "${targets}" -o "${objects}"
    done
}


# main
#
main()
{
    local start_stamp=$(date '+%Y-%m-%d-%H%M%S')

    gmb_config_global
    
    # logfile
    [ -d "${GMB_LOG_DIR}" ] || mkdir -p "${GMB_LOG_DIR}"
    GMB_LOGFILE="${GMB_LOG_DIR}/gmb.${start_stamp}.log"
    # [fixme] need to check if logfile exists?

    # cleanup run dir
    if [ -d "${GMB_RUN_DIR}" ]; then
        find "${GMB_RUN_DIR}" -mindepth 1 -maxdepth 1 | xargs rm -rf
    else
        mkdir -p "${GMB_RUN_DIR}"
    fi
    
    # process
    gmb_env_push
    parse_command_line ${@}
    gmb_env_pop
}


# go
main ${@}
